<template>
    <transition name="fade">
        <div v-show="visible" ref="instance" :class="[vertical?'vertical':'horizontal']"
         @mousedown="clickTrackHandler">
            <div ref="thumb" class="thumb" :style="style"
             @mousedown="clickThumbHandler">
            </div>
        </div>
    </transition>
</template>

<script setup lang="ts">


import { ref, onMounted, reactive, watchEffect, toRef, toRaw, inject, InjectionKey, computed, watch, onUpdated, CSSProperties, onBeforeMount } from "vue"
import { key } from "./thumb"
import {BAR_MAP,scrollbarContextKey} from "./constants"
import {isClient,useEventListener} from "@vueuse/core"


let props = defineProps({
    size: {
        type: Number,
        defalut: 0
    },
    move: {
        type: Number,
        default: 0
    },
    ratio:{
        type:Number,
    },
    vertical: {
        type:Boolean,
        defalut:false
    },
})

// const scrollbar = inject(scrollbarContextKey)
const scrollbar = inject(scrollbarContextKey)


const bar =computed(()=>BAR_MAP[props.vertical?"vertical":"horizontal"])
// console.log(bar.value,"bar")
// const instance = ref<HTMLDivElement>()
const instance = ref<HTMLDivElement>()
const thumb = ref<HTMLDivElement>()

const thumbState = ref<Partial<Record<'X' | 'Y', number>>>({})

let cursorDown = false //是否点击了thumb
// let cursorLeave = false //是否离开了thumb

//这是什么参数啊
let  originalOnSelectStart :|((this:GlobalEventHandlers,ev:Event)=>any)|null = isClient?
document.onselectstart:null

// 是否显示滚动条
let visible = ref(false)

// 动态样式
let style = computed(()=>{
   let styles:CSSProperties={}

   if(props.vertical){
    styles.transform = `translateY(${props.move}%)`
    styles.height = `${props.size}px`
   }else{
    styles.transform = `translateX(${props.move}%)`
    styles.width = `${props.size}px`
   }

   return styles

})

const offsetRatio = computed(()=>{
    if(!instance.value||!props.ratio)return 1
   return instance.value![bar.value.offset]**2/
    props.ratio/
    scrollbar!.wrapElement![bar.value.scrollSize]/
    thumb.value![bar.value.offset]

}
)

// 点击滚动条触发事件
const clickThumbHandler = (e:MouseEvent)=>{
    e.stopPropagation()
    if(e.ctrlKey || [1,2].includes(e.button)) return
    // window.getSelection()?.removeAllRanges()
    startDrag(e)
    // console.log(e,"yaohf")

    const el = e.currentTarget as HTMLDivElement
    if(!el)return
    thumbState.value[bar.value.axis] = el[bar.value.offset]-
    (e[bar.value.client]-el.getBoundingClientRect()[bar.value.direction])
}

//点击滚动条的轨道触发事件
const clickTrackHandler = (e:MouseEvent)=>{
    // e.stopPropagation()
    if(!thumb.value || !instance.value || !scrollbar?.wrapElement )return
    // console.log("穿墙了吗")
    const offset = Math.abs((e.target as HTMLElement).getBoundingClientRect()
    [bar.value.direction]-e[bar.value.client])

    const thumbHalf = thumb.value[bar.value.offset]/2
    const thumbPositionPercentage =
    ((offset-thumbHalf)*100*offsetRatio.value)/
    instance.value[bar.value.offset]

    // console.log(offset,thumbHalf,thumbPositionPercentage,"轨道")

    scrollbar.wrapElement[bar.value.scroll] =
    (thumbPositionPercentage*scrollbar.wrapElement[bar.value.scrollSize])
    /100

}

const startDrag = (e:MouseEvent)=>{
    // console.log("为什么不能移动")
    e.stopImmediatePropagation()
    cursorDown = true
    document.addEventListener("mousemove",mouseMoveDocumentHandler)
    document.addEventListener("mouseup",mouseUpDocumentHandler)
    // originalSelectStart = document.onselectstart
    originalOnSelectStart =document.onselectstart
    document.onselectstart = ()=>false
}

const mouseMoveDocumentHandler = (e:MouseEvent)=>{
    //   console.log("为什么不能移动")
   
    if (!instance.value || !thumb.value) return
    if(!cursorDown) return
    // const prevPage = thumbProps.value[bar.value.axis]
    // console.log("fefese")
    const prevPage = thumbState.value[bar.value.axis]

    if(!prevPage)return
    
    const offset = 
    (instance.value?.getBoundingClientRect()[bar.value.direction] 
    - e[bar.value.client])*-1
     
    const thumbClickPosition = thumb.value[bar.value.offset] - prevPage
    const thumbPositionPercentage = 
    ((offset-thumbClickPosition)*100*offsetRatio.value)/
    instance.value[bar.value.offset]

    scrollbar!.wrapElement[bar.value.scroll] =
    (thumbPositionPercentage *scrollbar!.wrapElement[bar.value.scrollSize])
    /100

    // console.log(offset,thumbClickPosition,thumbPositionPercentage,"why no move")

}

const mouseUpDocumentHandler = ()=>{    
    cursorDown = false
    thumbState.value[bar.value.axis] = 0
    document.removeEventListener("mousemove",mouseMoveDocumentHandler)
    document.removeEventListener("mouseup",mouseUpDocumentHandler)
    restoreOnselectstart()
    if(cursorDown) visible.value = false
}

// 鼠标在滚动条上时,显示滚动条
const mouseMoveScrollbarHandler = ()=>{
   
    visible.value = !!props.size
   
}
//鼠标离开滚动条是，隐藏滚动条
const mouseLeaveScrollbarHandler = ()=>{
    
    visible.value = false
}

onBeforeMount(()=>{
    restoreOnselectstart()
    document.removeEventListener("mouseup",mouseUpDocumentHandler)
})

const restoreOnselectstart = () => {
  if (document.onselectstart !== originalOnSelectStart)
    document.onselectstart = originalOnSelectStart
}
// 利用vueuse做一下事件监听
useEventListener(
  
  toRef(scrollbar!, 'scrollbarElement'),
  'mousemove',
  mouseMoveScrollbarHandler
)
useEventListener(
  toRef(scrollbar!, 'scrollbarElement'),
  'mouseleave',
  mouseLeaveScrollbarHandler
)

</script>

<style scoped lang="scss">

//过度效果
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.vertical {
    // background-color: red;
    position: absolute;
    top: 0;
    // height: 100%;
    width: 6px;
    right: 2px;
    bottom: 2px;
    z-index: 20;

    .thumb {
        border-radius: 6px;
        background-color: #909399;
        opacity: 0.4;
        cursor: pointer;
        &:hover {
            opacity: 0.7;
            background-color: #909399;
        }
    }
}

.horizontal{
    position: absolute;
    bottom: 2px;
    left: 2px;
    height: 6px;
    width: 100%;
    z-index: 20;
    border-radius: 4px;

    .thumb {
        height: 100%;
        border-radius: 6px;
        background-color: #909399;
        opacity: 0.4;
        cursor: pointer;
        &:hover {
            opacity: .7;
            background-color: #909399;
        }
    }
}
</style>